﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using HML.Design;

namespace HML
{
    /// <summary>
    /// 水波纹控件
    /// </summary>
    [Description("水波纹控件")]
    [DefaultProperty("Value")]
    [DefaultEvent("ValueChanged")]
    [TypeConverter(typeof(PropertyOrderConverter))]
    [Designer(typeof(WaterRipplesDesigner))]
    [ToolboxItem(true)]
    [ToolboxBitmap(typeof(WaterRipples), "Controls.WaterRipples.Resources.WaterRipples.bmp")]
    public class WaterRipples : MainThreadAnimationControl, ISkinObject
    {
        #region 主题

        private SkinObjectXmlMetadata skinObjectXmlMetadata = null;
        /// <summary>
        /// 主题对象在主题文件信息
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual SkinObjectXmlMetadata SkinObjectXmlMetadata
        {
            get
            {
                if (this.skinObjectXmlMetadata == null)
                    this.skinObjectXmlMetadata = new SkinObjectXmlMetadata(Assembly.GetAssembly(typeof(WaterRipples)).GetName().Name, typeof(WaterRipples).Name);

                return this.skinObjectXmlMetadata;
            }
        }

        private SkinController skinController = null;
        /// <summary>
        /// 主题控制器
        /// </summary>
        [Description("主题控制器")]
        [Category("杂项")]
        [PropertyOrder(-360)]
        [DefaultValue(null)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinController SkinController
        {
            get { return this.skinController; }
            set
            {
                if (this.skinController == value)
                    return;

                if (this.skinController != null)
                    this.skinController.RemoveSkinObject(this);

                this.skinController = value;

                if (this.skinController != null)
                    this.skinController.AddSkinObject(this);
            }
        }

        private SkinEnabledState skinEnabled = SkinEnabledState.Auto;
        /// <summary>
        /// 主题是否启用
        /// </summary>
        [Description("主题是否启用")]
        [Category("杂项")]
        [PropertyOrder(-300)]
        [DefaultValue(SkinEnabledState.Auto)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinEnabledState SkinEnabled
        {
            get { return this.skinEnabled; }
            set
            {
                if (this.skinEnabled == value)
                    return;

                this.skinEnabled = value;
                this.OnSkinChanged();
            }
        }

        private SkinStyle skinStyle = SkinStyle.Normal;
        /// <summary>
        /// 主题风格
        /// </summary>
        [Description("主题风格")]
        [Category("杂项")]
        [PropertyOrder(-260)]
        [DefaultValue(SkinStyle.Normal)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinStyle SkinStyle
        {
            get { return this.skinStyle; }
            set
            {
                if (this.skinStyle == value)
                    return;

                this.skinStyle = value;
                this.OnSkinChanged();
            }
        }

        private StyleAppearanceObject stateAppearance;
        /// <summary>
        /// 风格外观
        /// </summary>
        [Description("风格外观")]
        [Category("杂项")]
        [PropertyOrder(-200)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public StyleAppearanceObject StyleAppearance
        {
            get
            {
                if (this.stateAppearance == null)
                    this.stateAppearance = new StyleAppearanceObject(this, null);
                return this.stateAppearance;
            }
        }

        /// <summary>
        /// 主题已更改
        /// </summary>
        public virtual void OnSkinChanged()
        {
            SkinManager.SyncSkinValueToProperty(this);
            this.Invalidate();
        }

        private ISkinObject followSkinObject = null;
        /// <summary>
        /// 主题设置跟随指定主题对象（自己的设置不再生效，提供给代码使用）
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Localizable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual ISkinObject FollowSkinObject
        {
            get { return this.followSkinObject; }
            set
            {
                if (this.followSkinObject == value)
                    return;

                this.followSkinObject = value;
                this.OnSkinChanged();
            }
        }

        public virtual bool GetSkinObjectSkinStateCore()
        {
            return SkinManager.GetSkinObjectSkinState(this.FollowSkinObject ?? this);
        }

        void ISkinObject.InitializeInvalidate()
        {
            this.InitializeElement();
            this.Invalidate();
        }

        void ISkinObject.Invalidate()
        {
            this.Invalidate();
        }

        #endregion

        #region 新增事件

        private static readonly object EventValueChanged = new object();
        /// <summary>
        /// 值更改事件
        /// </summary>
        [Description("值更改事件")]
        public event EventHandler ValueChanged
        {
            add { Events.AddHandler(EventValueChanged, value); }
            remove { Events.RemoveHandler(EventValueChanged, value); }
        }

        public delegate void ValueFormatEventHandler(object sender, WaterRipplesValueFormatEventArgs e);
        private static readonly object EventValueFormat = new object();
        /// <summary>
        /// Value值格式化事件
        /// </summary>
        [Description("Value值格式化事件")]
        public event ValueFormatEventHandler ValueFormat
        {
            add { Events.AddHandler(EventValueFormat, value); }
            remove { Events.RemoveHandler(EventValueFormat, value); }
        }

        #endregion

        #region 停用事件

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler PaddingChanged
        {
            add { base.PaddingChanged += value; }
            remove { base.PaddingChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler TabIndexChanged
        {
            add { base.TabIndexChanged += value; }
            remove { base.TabIndexChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler TabStopChanged
        {
            add { base.TabStopChanged += value; }
            remove { base.TabStopChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler TextChanged
        {
            add { base.TextChanged += value; }
            remove { base.TextChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler RightToLeftChanged
        {
            add { base.RightToLeftChanged += value; }
            remove { base.RightToLeftChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ImeModeChanged
        {
            add { base.ImeModeChanged += value; }
            remove { base.ImeModeChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageChanged
        {
            add { base.BackgroundImageChanged += value; }
            remove { base.BackgroundImageChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageLayoutChanged
        {
            add { base.BackgroundImageLayoutChanged += value; }
            remove { base.BackgroundImageLayoutChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackColorChanged
        {
            add { base.BackColorChanged += value; }
            remove { base.BackColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ForeColorChanged
        {
            add { base.ForeColorChanged += value; }
            remove { base.ForeColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler Click
        {
            add { base.Click += value; }
            remove { base.Click -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler DoubleClick
        {
            add { base.DoubleClick += value; }
            remove { base.DoubleClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseClick
        {
            add { base.MouseClick += value; }
            remove { base.MouseClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseDoubleClick
        {
            add { base.MouseDoubleClick += value; }
            remove { base.MouseDoubleClick -= value; }
        }

        #endregion

        #region 新增属性

        private WaterRipplesStylePattern stylePattern = WaterRipplesStylePattern.Circle;
        /// <summary>
        /// 风格模式
        /// </summary>
        [Description("风格模式")]
        [Category("杂项")]
        [PropertyOrder(-198)]
        [DefaultValue(WaterRipplesStylePattern.Circle)]
        public WaterRipplesStylePattern StylePattern
        {
            get { return this.stylePattern; }
            set
            {
                if (this.stylePattern == value)
                    return;

                this.stylePattern = value;
                this.SetControlShape();
                this.Invalidate();
            }
        }

        private bool animationEnabled = false;
        /// <summary>
        /// 动画是否启动
        /// </summary>
        [Description("动画是否启动")]
        [Category("杂项")]
        [PropertyOrder(-196)]
        [DefaultValue(false)]
        public bool AnimationEnabled
        {
            get { return this.animationEnabled; }
            set
            {
                if (this.animationEnabled == value)
                    return;

                this.animationEnabled = value;
                this.Invalidate();

                if (!this.DesignMode && this.Visible && this.Enabled && this.AnimationEnabled && this.Parent != null)
                {
                    MainThreadAnimationControl.AnimationStart(this);
                }
                else
                {
                    MainThreadAnimationControl.AnimationStop(this);
                }
            }
        }

        private int borderThickness = 2;
        /// <summary>
        /// 边框厚度
        /// </summary>
        [Description("边框厚度")]
        [Category("杂项")]
        [PropertyOrder(-194)]
        [DefaultValue(2)]
        public int BorderThickness
        {
            get { return this.borderThickness; }
            set
            {
                if (this.borderThickness == value || value < 0)
                    return;

                this.borderThickness = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private Size waveSize = new Size(30, 10);
        /// <summary>
        /// 水波纹Size
        /// </summary>
        [Description("水波纹高度")]
        [Category("杂项")]
        [PropertyOrder(-192)]
        [DefaultValue(typeof(Size), "30,10")]
        public Size WaveSize
        {
            get { return this.waveSize; }
            set
            {
                if (this.waveSize == value || value.Width < 1 || value.Height < 1)
                    return;

                this.waveSize = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private int waveVelocity = 5;
        /// <summary>
        /// 水波纹移动速度(特定时间内移动像素)
        /// </summary>
        [Description("水波纹移动速度(特定时间内移动像素)")]
        [Category("杂项")]
        [PropertyOrder(-190)]
        [DefaultValue(5)]
        public int WaveVelocity
        {
            get { return this.waveVelocity; }
            set
            {
                if (this.waveVelocity == value || value <= 0)
                    return;

                this.waveVelocity = value;
            }
        }

        private bool valueVisible = true;
        /// <summary>
        /// 是否显示进度值
        /// </summary>
        [Description("是否显示进度值")]
        [Category("杂项")]
        [PropertyOrder(-188)]
        [DefaultValue(true)]
        public bool ValueVisible
        {
            get { return this.valueVisible; }
            set
            {
                if (this.valueVisible == value)
                    return;

                this.valueVisible = value;
                this.Invalidate();
            }
        }

        private double value = 0D;
        /// <summary>
        /// 进度值(0-100)
        /// </summary>
        [Description("进度值(0-100)")]
        [Category("杂项")]
        [PropertyOrder(-186)]
        [DefaultValue(0D)]
        public double Value
        {
            get { return this.value; }
            set
            {
                if (this.value == value)
                    return;

                if (value > 100)
                    value = 100;
                if (value < 0)
                    value = 0;
                this.value = value;
                this.Invalidate();

                this.OnValueChanged(new EventArgs());
            }
        }

        #endregion

        #region 重写属性

        protected override Size DefaultSize
        {
            get { return new Size(80, 80); }
        }

        protected override ImeMode DefaultImeMode
        {
            get { return ImeMode.Disable; }
        }

        #endregion

        #region 停用属性

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new Padding Padding
        {
            get { return base.Padding; }
            set { base.Padding = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new int TabIndex
        {
            get { return base.TabIndex; }
            set { base.TabIndex = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new bool TabStop
        {
            get { return base.TabStop; }
            set { base.TabStop = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override string Text
        {
            get { return base.Text; }
            set { base.Text = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override RightToLeft RightToLeft
        {
            get { return base.RightToLeft; }
            set { base.RightToLeft = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new ImeMode ImeMode
        {
            get { return base.ImeMode; }
            set { base.ImeMode = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Image BackgroundImage
        {
            get { return base.BackgroundImage; }
            set { base.BackgroundImage = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override ImageLayout BackgroundImageLayout
        {
            get { return base.BackgroundImageLayout; }
            set { base.BackgroundImageLayout = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color BackColor
        {
            get { return this.StyleAppearance.BackColor; }
            set { }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color ForeColor
        {
            get { return this.StyleAppearance.TextColor; }
            set { }
        }

        #endregion

        #region 字段

        /// <summary>
        /// 水波纹移动距离
        /// </summary>
        private int wave_distance = 0;
        /// <summary>
        /// 前面水波纹坐标
        /// </summary>
        private List<Point> waveFrontPointList = new List<Point>();
        /// <summary>
        /// 后面水波纹坐标
        /// </summary>
        private List<Point> waveBehindPointList = new List<Point>();

        /// <summary>
        /// 水波纹动画累加时间
        /// </summary>
        private double waveAccumulationTime = 0;

        #endregion

        public WaterRipples()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.StandardClick, false);
            SetStyle(ControlStyles.StandardDoubleClick, false);
            SetStyle(ControlStyles.Selectable, false);

            this.TabStop = false;
            this.InitializeElement();
            this.OnSkinChanged();
        }

        #region 重写

        protected override void OnScaleDpiChangedInitialize()
        {
            this.InitializeElement();
            this.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;

            int scale_borderthicknes = (int)Math.Ceiling(this.BorderThickness * this.ScaleDpi);
            Rectangle rect = new Rectangle(this.ClientRectangle.X + 1, this.ClientRectangle.Y + 1, this.ClientRectangle.Width - 2, this.ClientRectangle.Height - 2);

            // 水波纹背景
            SolidBrush waveback_sb = new SolidBrush(this.StyleAppearance.WaveBackColor);
            if (this.StylePattern == WaterRipplesStylePattern.Quadrangle)
            {
                g.FillRectangle(waveback_sb, new Rectangle(this.ClientRectangle.X + scale_borderthicknes, this.ClientRectangle.Y + scale_borderthicknes, this.ClientRectangle.Width - scale_borderthicknes * 2, this.ClientRectangle.Height - scale_borderthicknes * 2));
            }
            else
            {
                g.FillEllipse(waveback_sb, new Rectangle(rect.X + scale_borderthicknes / 2, rect.Y + scale_borderthicknes / 2, rect.Width - scale_borderthicknes, rect.Height - scale_borderthicknes));
            }
            waveback_sb.Dispose();

            // 水波纹
            if (this.waveFrontPointList.Count > 0 && this.Value > 0)
            {
                int scale_wave_height = (int)(this.WaveSize.Height * this.ScaleDpi);
                Point[] behindPoint = new Point[this.waveFrontPointList.Count + 2];
                Point[] frontPoint = new Point[this.waveFrontPointList.Count + 2];

                int value_h = (int)(this.Value / 100F * rect.Height);
                for (int i = 0; i < this.waveFrontPointList.Count; i++)
                {
                    behindPoint[i] = new Point(this.waveBehindPointList[i].X - this.wave_distance, rect.Bottom - this.waveBehindPointList[i].Y - value_h);
                    frontPoint[i] = new Point(this.waveFrontPointList[i].X + this.wave_distance, rect.Bottom - this.waveFrontPointList[i].Y - value_h + (int)(scale_wave_height / 3f));
                }

                behindPoint[this.waveFrontPointList.Count] = new Point(behindPoint[this.waveFrontPointList.Count - 1].X, rect.Bottom);
                behindPoint[this.waveFrontPointList.Count + 1] = new Point(behindPoint[0].X, rect.Bottom);

                frontPoint[this.waveFrontPointList.Count] = new Point(frontPoint[this.waveFrontPointList.Count - 1].X, rect.Bottom);
                frontPoint[this.waveFrontPointList.Count + 1] = new Point(frontPoint[0].X, rect.Bottom);

                SolidBrush behind_sb = new SolidBrush(this.StyleAppearance.WaveBehindColor);
                SolidBrush front_sb = new SolidBrush(this.StyleAppearance.WaveFrontColor);

                GraphicsPath commom_gp = new GraphicsPath();
                if (this.StylePattern == WaterRipplesStylePattern.Quadrangle)
                {
                    commom_gp.AddRectangle(new Rectangle(this.ClientRectangle.X + scale_borderthicknes, this.ClientRectangle.Y + scale_borderthicknes, this.ClientRectangle.Width - scale_borderthicknes * 2, this.ClientRectangle.Height - scale_borderthicknes * 2));
                }
                else
                {
                    commom_gp.AddEllipse(new Rectangle(rect.X + scale_borderthicknes / 2, rect.Y + scale_borderthicknes / 2, rect.Width - scale_borderthicknes, rect.Height - scale_borderthicknes));
                }
                GraphicsPath behind_gp = new GraphicsPath();
                behind_gp.AddClosedCurve(behindPoint);
                Region behind_r = new Region(behind_gp);
                behind_r.Intersect(commom_gp);
                g.FillRegion(behind_sb, behind_r);
                behind_gp.Dispose();
                behind_r.Dispose();

                GraphicsPath front_gp = new GraphicsPath();
                front_gp.AddClosedCurve(frontPoint);
                Region front_r = new Region(front_gp);
                front_r.Intersect(commom_gp);
                g.FillRegion(front_sb, front_r);
                front_gp.Dispose();
                front_r.Dispose();

                commom_gp.Dispose();
                front_sb.Dispose();
                behind_sb.Dispose();
            }

            //边框
            if (this.BorderThickness > 0)
            {
                if (this.StylePattern == WaterRipplesStylePattern.Quadrangle)
                {
                    Pen border_pen = new Pen(this.StyleAppearance.BorderColor, scale_borderthicknes) { Alignment = PenAlignment.Inset };
                    g.DrawRectangle(border_pen, new Rectangle(this.ClientRectangle.X, this.ClientRectangle.Y, this.ClientRectangle.Width - scale_borderthicknes, this.ClientRectangle.Height - scale_borderthicknes));
                    border_pen.Dispose();
                }
                else
                {
                    Pen border_pen = new Pen(this.StyleAppearance.BorderColor, scale_borderthicknes) { Alignment = PenAlignment.Center };
                    g.DrawEllipse(border_pen, new Rectangle(rect.X + scale_borderthicknes / 2, rect.Y + scale_borderthicknes / 2, rect.Width - scale_borderthicknes, rect.Height - scale_borderthicknes));
                    border_pen.Dispose();
                }
            }

            g.SmoothingMode = SmoothingMode.Default;

            // 进度值
            if (this.ValueVisible)
            {
                string text_str = ControlHelper.ReserveDecimals(this.Value.ToString(), 2) + "%";
                if ((Events[EventValueChanged] as EventHandler) != null)
                {
                    WaterRipplesValueFormatEventArgs arg = new WaterRipplesValueFormatEventArgs(this.Value, text_str);
                    this.OnValueFormat(arg);
                    text_str = arg.ValueFormat;
                }
                SizeF text_size = g.MeasureString(text_str, this.Font, int.MaxValue, StringFormat.GenericTypographic);
                SolidBrush text_sb = new SolidBrush(this.StyleAppearance.TextColor);
                g.DrawString(text_str, this.Font, text_sb, new PointF((rect.Width - text_size.Width) / 2f, rect.Height / 3f), StringFormat.GenericTypographic);
                text_sb.Dispose();
            }
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);

            if (this.DesignMode)
                return;

            if (this.Visible && this.Enabled && this.AnimationEnabled && this.Parent != null && this.FindForm() != null)
            {
                MainThreadAnimationControl.AnimationStart(this);
            }
            else
            {
                MainThreadAnimationControl.AnimationStop(this);
            }
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);

            if (this.DesignMode)
                return;

            if (this.Visible && this.Enabled && this.AnimationEnabled && this.Parent != null && this.FindForm() != null)
            {
                MainThreadAnimationControl.AnimationStart(this);
            }
            else
            {
                MainThreadAnimationControl.AnimationStop(this);
            }
        }

        protected override void OnParentChanged(EventArgs e)
        {
            base.OnParentChanged(e);

            if (this.DesignMode)
                return;

            if (this.Visible && this.Enabled && this.AnimationEnabled && this.Parent != null && this.FindForm() != null)
            {
                MainThreadAnimationControl.AnimationStart(this);
            }
            else
            {
                MainThreadAnimationControl.AnimationStop(this);
            }
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);

            this.SetControlShape();
            this.InitializeElement();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                MainThreadAnimationControl.AnimationStop(this);
            }
            base.Dispose(disposing);
        }

        /// <summary>
        /// 动画控件动画中要处理的内容(不能时耗时操作)
        /// </summary>
        /// <param name="interval">动画定时器间隔时间</param>
        protected override void Animationing(int interval)
        {
            this.waveAccumulationTime += interval;
            if (this.waveAccumulationTime > 100)
            {
                this.waveAccumulationTime = 0;

                this.wave_distance += (int)(this.WaveVelocity * this.ScaleDpi);
                if (this.wave_distance >= this.WaveSize.Width * this.ScaleDpi * 2)
                {
                    this.wave_distance = 0;
                }

                this.Invalidate();
            }
        }

        #endregion

        #region 虚方法

        protected virtual void OnValueChanged(EventArgs e)
        {
            EventHandler handler = Events[EventValueChanged] as EventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnValueFormat(WaterRipplesValueFormatEventArgs e)
        {
            ValueFormatEventHandler handler = Events[EventValueFormat] as ValueFormatEventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        #endregion

        #region 公开方法

        /// <summary>
        /// 初始化控件内部元素布局
        /// </summary>
        public void InitializeElement()
        {
            int scale_width = (int)(this.WaveSize.Width * this.ScaleDpi);
            int scale_height = (int)(this.WaveSize.Height * this.ScaleDpi);
            this.waveFrontPointList.Clear();
            this.waveBehindPointList.Clear();
            int startFront_x = this.ClientRectangle.Left - scale_width * 4;
            int start_y = 0;
            int startBehind_x = this.ClientRectangle.Right + scale_width * 4;

            int i = 0;
            while (true)
            {
                startFront_x += scale_width;
                startBehind_x -= scale_width;
                start_y = scale_height * (i % 2);
                this.waveFrontPointList.Add(new Point(startFront_x, start_y));
                this.waveBehindPointList.Add(new Point(startBehind_x, start_y));
                if (startFront_x >= this.ClientRectangle.Right && start_y == 0)
                {
                    this.wave_distance = 0;
                    return;
                }
                i++;
            }
        }

        #endregion 

        #region 私有方法

        /// <summary>
        /// 设置控件形状
        /// </summary>
        private void SetControlShape()
        {
            Region r = null;
            if (this.stylePattern == WaterRipplesStylePattern.Quadrangle)
            {
                r = new Region(this.ClientRectangle);
            }
            else
            {
                GraphicsPath gp = new GraphicsPath();
                gp.AddEllipse(this.ClientRectangle);
                r = new Region(gp);
                gp.Dispose();
            }
            this.Region = r;
        }

        #endregion

        #region 外观

        public class StyleAppearanceObject : AppearanceObjectBase
        {
            internal StyleAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

            #region 属性

            private Color skinBorderColor = Color.Empty;
            private readonly Color defaultBorderColor = SystemColors.ActiveCaption;
            private Color borderColor = Color.Empty;
            /// <summary>
            /// 边框颜色
            /// </summary>
            [Description("边框颜色")]
            [PropertyOrder(-159)]
            [SkinProperty(true, false)]
            public Color BorderColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinBorderColor;
                    }

                    if (this.borderColor != Color.Empty)
                    {
                        return this.borderColor;
                    }

                    return this.defaultBorderColor;
                }
                set
                {
                    if (this.borderColor == value)
                        return;

                    this.borderColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeBorderColor()
            {
                return this.borderColor != Color.Empty;
            }
            private void ResetBorderColor()
            {
                this.borderColor = Color.Empty;
                this.Invalidate();
            }

            private Color skinBackColor = Color.Empty;
            private readonly Color defaultBackColor = SystemColors.Control;
            private Color backColor = Color.Empty;
            /// <summary>
            /// 背景颜色
            /// </summary>
            [Description("背景颜色")]
            [PropertyOrder(-195)]
            [SkinProperty(true, true)]
            public Color BackColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore() && this.skinBackColor != Color.Empty)
                    {
                        return this.skinBackColor;
                    }

                    if (this.backColor != Color.Empty)
                    {
                        return this.backColor;
                    }

                    if (((Control)this.owner).Parent != null)
                    {
                        return ((Control)this.owner).Parent.BackColor;
                    }

                    return this.defaultBackColor;
                }
                set
                {
                    if (this.backColor == value)
                        return;

                    this.backColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeBackColor()
            {
                return this.backColor != Color.Empty;
            }
            private void ResetBackColor()
            {
                this.backColor = Color.Empty;
                this.Invalidate();
            }

            private Color skinTextColor = Color.Empty;
            private readonly Color defaultTextColor = SystemColors.ActiveCaption;
            private Color textColor = Color.Empty;
            /// <summary>
            /// 文本颜色
            /// </summary>
            [Description("文本颜色")]
            [PropertyOrder(-194)]
            [SkinProperty(true, false)]
            public Color TextColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinTextColor;
                    }

                    if (this.textColor != Color.Empty)
                    {
                        return this.textColor;
                    }

                    return this.defaultTextColor;
                }
                set
                {
                    if (this.textColor == value)
                        return;

                    this.textColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeTextColor()
            {
                return this.textColor != Color.Empty;
            }
            private void ResetTextColor()
            {
                this.textColor = Color.Empty;
                this.Invalidate();
            }

            private Color skinWaveBackColor = Color.Empty;
            private readonly Color defaultWaveBackColor = SystemColors.Window;
            private Color waveBackColor = Color.Empty;
            /// <summary>
            /// 水波纹背景颜色
            /// </summary>
            [Description("水波纹背景颜色")]
            [PropertyOrder(-188)]
            [Editor(typeof(AlphaColorEditor), typeof(UITypeEditor))]
            [SkinProperty(true, false)]
            public Color WaveBackColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinWaveBackColor;
                    }

                    if (this.waveBackColor != Color.Empty)
                    {
                        return this.waveBackColor;
                    }

                    return this.defaultWaveBackColor;
                }
                set
                {
                    if (this.waveBackColor == value)
                        return;

                    this.waveBackColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeWaveBackColor()
            {
                return this.waveBackColor != Color.Empty;
            }
            private void ResetWaveBackColor()
            {
                this.waveBackColor = Color.Empty;
                this.Invalidate();
            }

            private Color skinWaveBehindColor = Color.Empty;
            private readonly Color defaultWaveBehindColor = SystemColors.GradientInactiveCaption;
            private Color waveBehindColor = Color.Empty;
            /// <summary>
            /// 水波纹后方颜色
            /// </summary>
            [Description("水波纹后方颜色")]
            [PropertyOrder(-186)]
            [Editor(typeof(AlphaColorEditor), typeof(UITypeEditor))]
            [SkinProperty(true, false)]
            public Color WaveBehindColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinWaveBehindColor;
                    }

                    if (this.waveBehindColor != Color.Empty)
                    {
                        return this.waveBehindColor;
                    }

                    return this.defaultWaveBehindColor;
                }
                set
                {
                    if (this.waveBehindColor == value)
                        return;

                    this.waveBehindColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeWaveBehindColor()
            {
                return this.waveBehindColor != Color.Empty;
            }
            private void ResetWaveBehindColor()
            {
                this.waveBehindColor = Color.Empty;
                this.Invalidate();
            }

            private Color skinWaveFrontColor = Color.Empty;
            private readonly Color defaultWaveFrontColor = SystemColors.GradientActiveCaption;
            private Color waveFrontColor = Color.Empty;
            /// <summary>
            /// 水波纹前方颜色
            /// </summary>
            [Description("水波纹前方颜色")]
            [PropertyOrder(-184)]
            [Editor(typeof(AlphaColorEditor), typeof(UITypeEditor))]
            [SkinProperty(true, false)]
            public Color WaveFrontColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinWaveFrontColor;
                    }

                    if (this.waveFrontColor != Color.Empty)
                    {
                        return this.waveFrontColor;
                    }

                    return this.defaultWaveFrontColor;
                }
                set
                {
                    if (this.waveFrontColor == value)
                        return;

                    this.waveFrontColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeWaveFrontColor()
            {
                return this.waveFrontColor != Color.Empty;
            }
            private void ResetWaveFrontColor()
            {
                this.waveFrontColor = Color.Empty;
                this.Invalidate();
            }

            #endregion

        }

        #endregion

    }

}
